<?php
/**
 * Nuwani PHP IRC Bot Framework
 * Copyright (c) 2006-2010 The Nuwani Project
 *
 * Nuwani is a framework for IRC Bots built using PHP. Nuwani speeds up bot 
 * development by handling basic tasks as connection- and bot management, timers
 * and module managing. Features for your bot can easily be added by creating
 * your own modules, which will receive callbacks from the framework.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @copyright Copyright (c) 2006-2011 The Nuwani Project
 * @author Peter Beverloo <peter@lvp-media.com>
 * @author Dik Grapendaal <dik.grapendaal@gmail.com>
 * @see http://nuwani.googlecode.com
 */

//namespace Nuwani;

/**
 * Uno Nuwani Module
 * 
 * @copyright Copyright (c) 2011 The Nuwani Project, http://nuwani.googlecode.com/
 * @author Dik Grapendaal <dik.grapendaal@gmail.com>
 * @version $Id: UnoCard.php 141 2011-07-23 21:47:01Z dik.grapendaal $
 * @package Modules
 */

class UnoCard
{
        /**
         * The color of this card.
         * 
         * @var integer
         */
        
        private $mColor;
        
        /**
         * The number of this card. This includes special types, such as skip,
         * reverse or draw.
         * 
         * @var integer
         */
        
        private $mNumber;
        
        /**
         * In case this card is a wildcard, this property represents the color
         * specified by the player that played this wildcard and must match the
         * card that's going to be placed on this one.
         * 
         * @var integer
         */
        
        private $mNextColor;
        
        /**
         * Constructor sets up the card object. The color and number of this 
         * object is immutable.
         * 
         * @param int $color The color of the card.
         * @param int $number The number of the card.
         * @param int $nextColor If it's a wildcard, the color that needs to be played.
         */
        
        public function __construct ($color, $number, $nextColor = null)
        {
                $this -> mColor = $color;
                $this -> mNumber = $number;
                $this -> setNextColor ($nextColor);
        }
        
        /**
         * A sorting callback for use in usort() when sorting an array of cards.
         * 
         * @param UnoCard $c1 A UnoCard object.
         * @param UnoCard $c2 A UnoCard object.
         * @return integer
         */
        
        public static function compare (UnoCard $c1, UnoCard $c2)
        {
                // Color takes precedence.
                if ($c1 -> isSameColor ($c2 -> getColor ()))
                {
                        // Compare number instead.
                        if ($c1 -> isSameNumber ($c2 -> getNumber ()))
                        {
                                return 0;
                        }
                        
                        return ($c1 -> getNumber () < $c2 -> getNumber ()) ? -1 : 1;
                }
                
                return ($c1 -> getColor () < $c2 -> getColor ()) ? -1 : 1;
        }
        
        /**
         * Returns the color of this card.
         * 
         * @return integer
         */
        
        public function getColor ()
        {
                return $this -> mColor;
        }
        
        /**
         * Returns the number of this card. This also includes the special ones,
         * such as skip, reverse and draw.
         * 
         * @return integer
         */
        
        public function getNumber ()
        {
                return $this -> mNumber;
        }
        
        /**
         * Returns the color specified by the player that played this wildcard
         * and must match the card that's going to be placed on this one.
         * 
         * @return integer
         */
        
        public function getNextColor ()
        {
                return $this -> mNextColor;
        }
        
        /**
         * Sets the color that needs to be played after this wildcard. If it's a
         * wildcard, that is.
         * 
         * @param int $color The color to change to.
         */
        
        public function setNextColor ($color)
        {
                if ($this -> isWildcard ())
                {
                        $this -> mNextColor = $color;
                }
        }
        
        /**
         * Shortcut method combining the isSameColor() and isSameNumber()
         * methods into one easy call.
         * 
         * @param int $color The color to check.
         * @param int $number The number to check.
         * @return boolean
         */
        
        public function isSame ($color, $number)
        {
                return $this -> isSameColor ($color) && $this -> isSameNumber ($number);
        }
        
        /**
         * Checks whether the given card and this card have the same color and
         * number.
         * 
         * @param UnoCard $card The card to check against.
         * @return boolean
         */
        
        public function isSameCard (UnoCard $card)
        {
                return $card -> isSameColor ($this -> getColor ())
                        && $card -> isSameNumber ($this -> getNumber ());
        }
        
        /**
         * Returns whether we the given color is the same as the one this card
         * object represents.
         * 
         * @param int $color The color to check.
         * @return boolean
         */
        
        public function isSameColor ($color)
        {
                return $this -> mColor === $color;
        }
        
        /**
         * Returns whether we the given number is the same as the one this card
         * object represents.
         * 
         * @param int $number The number to check.
         * @return boolean
         */
        
        public function isSameNumber ($number)
        {
                return $this -> mNumber === $number;
        }
        
        /**
         * Returns whether this card is a wildcard.
         * 
         * @return boolean
         */
        
        public function isWildcard ()
        {
                return $this -> isSameColor (UnoEngine :: COLOR_WILDCARD);
        }
        
        /**
         * Formats this card with the given UnoOutput object.
         * 
         * @param UnoOutput $output The class handling all Uno output.
         * @return string
         */
        
        public function format (UnoOutput $output)
        {
                return $output -> formatCard ($this);
        }
        
        /**
         * Returns an array with the internal representation of a card to
         * indicate what kind of card was assigned.
         * 
         * @return array
         */
        
        public function toArray ()
        {
                return array
                (
                        UnoEngine :: INDEX_INPUT  => UnoEngine :: INPUT_SINGLE,
                        UnoEngine :: INDEX_COLOR  => $this -> getColor (),
                        UnoEngine :: INDEX_NUMBER => $this -> getNumber (),
                        UnoEngine :: INDEX_NEXT   => $this -> getNextColor ()
                );
        }
}